import dayjs from 'dayjs'
export const cache = {
    write(key, data, isSession) {
        let storage = isSession ? sessionStorage : localStorage;
        let storageData;
        try {
            storageData = JSON.stringify(data)
        } catch (err) {
            storageData = data
        }
        storage[key] = storageData
    },
    read(key, isSession) {
        let storage = isSession ? sessionStorage : localStorage;
        let data = storage[key]
        let storageData;
        try {
            storageData = JSON.parse(data)
        } catch (err) {
            storageData = data
        }

        if(storageData instanceof Object) {
            if(Object.keys(storageData).length == 2 && typeof storageData.type == 'string' && typeof storageData.data == 'object') {
                storageData = storageData.data
            }
        }
        return storageData
    },
    remove(key) {
        localStorage.removeItem(key)
        sessionStorage.removeItem(key)
    }
}
// 防抖函数
export const debounce = (fn, delay = 200) => {
    let timer = null;
    return function () {
        clearTimeout(timer)
        timer = setTimeout(() => {
            fn.apply(this, arguments)
            timer = null
        }, delay)
    }
}
// 节流函数
export const throttle = (fn, delay = 200) => {
    let canRun = true;
    return function () {
        if (!canRun) return;
        fn.apply(this, arguments);
        canRun = false;
        setTimeout(() => {
            canRun = true;
        }, delay);
    };
}

export function deepCopy(obj) {
    let objClone =  Array.isArray(obj) ? [] : {};
    if (obj && typeof obj === 'object') {
        for(let key in obj){
            if (obj[key] && (obj[key] instanceof Object || obj[key] instanceof Array)){
                if(obj[key] instanceof Date) {
                    objClone[key] = obj[key]
                } else {
                    objClone[key] = deepCopy(obj[key]);
                }
            }else{
                objClone[key] = obj[key]
            }
        }
    }
    return objClone;
}


export function trueeOpen(arr) {
    return arr.reduce((acc, cur) => {
        if (Array.isArray(cur.subs)) {
            const copyCur = { ...cur }
            delete copyCur.subs
            return acc.concat(copyCur, trueeOpen(cur.subs))
        } else {
            return acc.concat(cur)
        }
    }, [])
}


/**
 *
 * type day(日)，week(周),month(月)，quarter(季度),year(年), minute(分钟), second(秒)
 * format 'YYYY-MM-DD HH:mm:ss
 *
*/
export function createRangeTime(type, format = 'YYYY-MM-DD', date = new Date()) {
    const now = dayjs(date);
    const start = now.startOf(type).format(format);
    const end = now.endOf(type).format(format);
    return [start, end]
}




export function gcj02towgs84 (lng, lat) {
    // 腾讯使用的是gcj02 转国测局的定位，天地图是国测局的定位
    // 天地图使用的是CGCS2000坐标系，这是一个地心坐标系，与WGS84坐标系相差不大
    //定义一些常量
    var PI = 3.1415926535897932384626;
    var a = 6378245.0;
    var ee = 0.00669342162296594323;

    let transformlat = function (lng, lat) {
        var ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
        ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0;
        ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0;
        return ret
    }

    let transformlng = function (lng, lat) {
        var ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
        ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0;
        ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0;
        return ret
    }


    let out_of_china = function (lng, lat) {
        return (lng < 72.004 || lng > 137.8347) || ((lat < 0.8293 || lat > 55.8271) || false);
    }



    if (out_of_china(lng, lat)) {
        return [lng, lat]
    } else {
        var dlat = transformlat(lng - 105.0, lat - 35.0);
        var dlng = transformlng(lng - 105.0, lat - 35.0);
        var radlat = lat / 180.0 * PI;
        var magic = Math.sin(radlat);
        magic = 1 - ee * magic * magic;
        var sqrtmagic = Math.sqrt(magic);
        dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
        dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);
        let mglat = lat + dlat;
        let mglng = lng + dlng;
        // return [lng * 2 - mglng, lat * 2 - mglat]
        return {
            lng: lng * 2 - mglng,
            lat: lat * 2 - mglat
        }
    }
}





export function wgs84ToGcj02(lng, lat) {
    const xPI = (3.14159265358979324 * 3000.0) / 180.0;
    const PI = 3.1415926535897932384626;
    const a = 6378245.0;
    const ee = 0.00669342162296594323;


    const transformlat = (lng, lat) => {
        const PI = 3.1415926535897932384626;
        let ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
        ret += ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0) / 3.0;
        ret += ((20.0 * Math.sin(lat * PI) + 40.0 * Math.sin((lat / 3.0) * PI)) * 2.0) / 3.0;
        ret += ((160.0 * Math.sin((lat / 12.0) * PI) + 320 * Math.sin((lat * PI) / 30.0)) * 2.0) / 3.0;
        return ret;
    }

    const transformlng = (lng, lat) => {
        const PI = 3.1415926535897932384626;
        let ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
        ret += ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0) / 3.0;
        ret += ((20.0 * Math.sin(lng * PI) + 40.0 * Math.sin((lng / 3.0) * PI)) * 2.0) / 3.0;
        ret += ((150.0 * Math.sin((lng / 12.0) * PI) + 300.0 * Math.sin((lng / 30.0) * PI)) * 2.0) / 3.0;
        return ret;
    }

    // WGS84转GCj02
    let dlat = transformlat(lng - 105.0, lat - 35.0);
    let dlng = transformlng(lng - 105.0, lat - 35.0);
    let radlat = (lat / 180.0) * PI;
    let magic = Math.sin(radlat);
    magic = 1 - ee * magic * magic;
    let sqrtmagic = Math.sqrt(magic);
    dlat = (dlat * 180.0) / (((a * (1 - ee)) / (magic * sqrtmagic)) * PI);
    dlng = (dlng * 180.0) / ((a / sqrtmagic) * Math.cos(radlat) * PI);
    let mglat = lat + dlat;
    let mglng = lng + dlng;
    // 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换
    let z = Math.sqrt(mglng * mglng + mglat * mglat) + 0.00002 * Math.sin(mglat * xPI);
    let theta = Math.atan2(mglat, mglng) + 0.000003 * Math.cos(mglng * xPI);
    let bdlng = z * Math.cos(theta) + 0.0065;
    let bdlat = z * Math.sin(theta) + 0.006;
    // return [bdlng, bdlat]

    /*  Object.assign({}, target, source)，其中第一个参数是一个空对象，第二个参数是目标对象，第三个参数是源对象。该方法会将源对象中不存在于目标对象中的属性复制到目标对象中，而不会覆盖目标对象中已经存在的同名属性。 */
    return Object.assign({}, {longitude: bdlng, latitude: bdlat});
}





export function getRangeMap(type, formater = 'YYYY-MM-DD') {
    let now = dayjs(new Date())
    let dateMap = {
        today: [now.format(formater), now.format(formater)],
        yesterday: [ now.subtract(1, 'day').format(formater), now.subtract(1, 'day').format(formater)],
        week: [ now.startOf('week').format(formater), now.endOf('week').format(formater) ],
        lastWeek: [ now.subtract(1, 'week').startOf('week').format(formater), now.subtract(1, 'week').endOf('week').format(formater)],
        month: [ now.startOf('month').format(formater), now.endOf('month').format(formater) ],
        lastMonth: [ now.subtract(1, 'month').startOf('month').format(formater), now.subtract(1, 'month').endOf('month').format(formater)],
        quarter: [ now.startOf('quarter').format(formater), now.endOf('quarter').format(formater) ] ,
        lastQuarter: [ now.subtract(1, 'quarter').startOf('quarter').format(formater), now.subtract(1, 'quarter').endOf('quarter').format(formater)],
        year: [ now.startOf('year').format(formater), now.endOf('year').format(formater) ],
    }
    if(type) {
        return dateMap[type]
    } else {
        return dateMap
    }
}
